/**
 * Copyright 2010 Creative Works, Inc.
 * Creative Works licenses this file to you under the Apache License, version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.sendvox.freswitch.core;

import java.util.List;

import org.jboss.netty.channel.Channel;

public interface SendMsg {

	/**
	 * @param uuid
	 *            the uuid to set
	 */
	public abstract SendMsg uuid(String uuid);

	/**
	 * @param callCommand
	 *            the callCommand to set
	 */
	public abstract SendMsg callCommand(CallCommand callCommand);

	/**
	 * @param executeAppName
	 *            the executeAppName to set
	 */
	public abstract SendMsg executeAppName(String executeAppName);

	/**
	 * @param executeAppName
	 *            the executeAppName to set
	 */
	public abstract SendMsg executeAppName(Application executeAppName);

	/**
	 * @param executeAppArg
	 *            the executeAppArg to set
	 */
	public abstract SendMsg executeAppArg(String executeAppArg);

	/**
	 * Number of times to invoke the command, default: 1
	 * 
	 * @param loops
	 *            the loops to set
	 */
	public abstract SendMsg loops(Integer loops);

	/**
	 * <code> hangup-cause: [one of the causes listed in the <a href="http://wiki.freeswitch.org/wiki/Hangup_Causes">Hangup Causes</a> page] </code>
	 */
	public abstract SendMsg hangupCause(String hangupCause);

	/**
	 * Sets event-lock: true
	 */
	public abstract SendMsg eventLock(boolean eventLock);

	/**
	 * Sets nomedia-uuid: <noinfo>
	 */
	public abstract SendMsg nomedia(String noinfo);

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	public abstract String toString();

	/**
	 * @return the command
	 */
	public abstract List<String> getCommand();

	/**
	 * @return the uuid
	 */
	public abstract String getUuid();

	/**
	 * @return the callCommand
	 */
	public abstract CallCommand getCallCommand();

	/**
	 * @return the executeAppName
	 */
	public abstract String getExecuteAppName();

	/**
	 * @return the executeAppArg
	 */
	public abstract String getExecuteAppArg();

	/**
	 * @return the loops
	 */
	public abstract Integer getLoops();

	/**
	 * @return the hangupCause
	 */
	public abstract String getHangupCause();

	/**
	 * @return the eventLock
	 */
	public abstract boolean isEventLock();

	/**
	 * @return the noMediaInfo
	 */
	public abstract String getNoMediaInfo();

	public enum CallCommand {

		/**
		 * <p>
		 * Execute are used to execute applications, check the Dialplan XML
		 * section for more information about all commands.
		 * </p>
		 * <p>
		 * The format should be: <br/>
		 * <br/>
		 * <code> SendMsg &lt;uuid&gt;</code> <br/>
		 * <code> call-command: execute </code><br/>
		 * <code> execute-app-name: &lt;one of the applications&gt; <br/>
		 * <code> execute-app-arg: &lt;application data&gt; <br/>
		 * <code> loops: &lt;number of times to invoke the command, default: 1&gt; </code>
		 * <br/>
		 * </p>
		 */
		EXECUTE("execute"),

		/**
		 * <p>
		 * Hangup the call.
		 * </p>
		 * <p>
		 * Format: <br/>
		 * <br/>
		 * <code> SendMsg &lt;uuid&gt;</code> <br/>
		 * <code> call-command: hangup </code>
		 * <code> hangup-cause: [one of the causes listed in the <a href="http://wiki.freeswitch.org/wiki/Hangup_Causes">Hangup Causes</a> page] </code>
		 */
		HANGUP("hangup"),
		
		/**
		 * nomedia No description.
		 * <p>
		 * <code> SendMsg &lt;uuid&gt;</code> <br/>
		 * <code> call-command: nomedia </code>
		 * <code> nomedia-uuid: &lt;noinfo&gt; </code>
		 * </p>
		 */
		NOMEDIA("nomedia");

		private final String literal;

		private CallCommand(String literal) {
			this.literal = literal;
		}

		public String getLiteral() {
			return literal;
		}

		public static CallCommand fromLiteral(String literal) {
			for (CallCommand header : values()) {
				if (header.literal.equalsIgnoreCase(literal)) {
					return header;
				}
			}
			return null;
		}
	}

	public abstract SendMsg execute(Channel channel) throws CommandException;

}